#include <REGX52.H>
#include "timer0.h"
#include "Int0.h"

// 计时
unsigned int IR_time;
// 状态，0：空闲，1：接收Start/Repeat数据，2：接收数据
unsigned char IR_state;
// 红外数据
unsigned char IR_data[4];
// 当前指向数据的位置（IR_Data）
unsigned char IR_pData;

// 数据接收结束标志位，1：是，0：否。
unsigned char IR_dataFlag;
// 循环标志位，1：是，0：否。
unsigned char IR_repeatFlag;
// 接收的地址码
unsigned char IR_address;
// 接收的命令码
unsigned char IR_command;

/** @bref 红外数据处理初始化
  * @param 无
  * @retval 无
  */
void IR_init()
{
	timer0_init();
	Int0_init();
}

/** @bref 获取循环标志位
  * @param 无
  * @retval 循环标志位
  */
unsigned char IR_getDataFlag()
{
	if(IR_dataFlag)
	{
		IR_dataFlag = 0;
		return 1;
	}
	
	return 0;
}

/** @bref 获取数据接收结束标志位
  * @param 无
  * @retval 数据接收结束标志位
  */
unsigned char IR_getRepeatFlag()
{
	if(IR_repeatFlag)
	{
		IR_repeatFlag = 0;
		return 1;
	}
	
	return 0;
}

/** @bref 获取地址码
  * @param 无
  * @retval 地址码
  */
unsigned char IR_getAddress()
{
	return IR_address;
}

/** @bref 获取命令码
  * @param 无
  * @retval 命令码
  */
unsigned char IR_getCommand()
{
	return IR_command;
}	

// 外部中断函数(下降沿触发)
void Int0_routine() interrupt 0
{
	// 若是空闲状态
	if(IR_state == 0)
	{
		// 开始计时
		timer0_setCounter(0);
		// 计时器启动
		timer0_run(1);
		// 设置为接收Start/Repeat数据的状态
		IR_state = 1;
	}
	// 若是接收Start/Repeat数据的状态
	else if(IR_state == 1)
	{
		// 获取上次中断到本次中断的时间
		IR_time = timer0_getCounter();
		// 计时器清0
		timer0_setCounter(0);
		// 若接收时间范围是Start信号（判定值在12MHz晶振下为13500，在11.0592MHz晶振下为12442）
		if((IR_time > 12442 - 500) && (IR_time < 12442 + 500))
		{
			IR_state == 2;
		}
		// 若接收时间范围是Repeat信号（判定值在12MHz晶振下为11250，在11.0592MHz晶振下为10368）
		else if((IR_time > 10368 - 500) && (IR_time < 10368 + 500))
		{
			IR_repeatFlag = 1;
			// 计时器停止
			timer0_run(0);
			IR_state == 0;
		}
		// 若接收时间不在正常范围内
		else
		{
			IR_state == 1;
		}
	}
	// 若是接收数据的状态
	else if(IR_state == 2)
	{
		// 获取上次中断到本次中断的时间
		IR_time = timer0_getCounter();
		// 计时器清0
		timer0_setCounter(0);
		// 若接收数据是0（判定值在12MHz晶振下为1120，在11.0592MHz晶振下为1032）
		if((IR_time > 1032 - 500) && (IR_time < 1032 + 500))
		{
			// 数据对应位清0
			IR_data[IR_pData/8] &= ~(0x01 << (IR_pData%8));
			IR_pData++;
		}
		// 若接收数据是1（判定值在12MHz晶振下为2250，在11.0592MHz晶振下为2074）
		else if((IR_time > 2074 - 500) && (IR_time < 2074 + 500))
		{
			// 数据对应位置1
			IR_data[IR_pData/8] |= (0x01 << (IR_pData%8));
			IR_pData++;
		}
		// 接收出错
		else
		{
			IR_pData = 0;
			IR_state = 1;
		}
	}
	
	// 若接收数据完毕
	if(IR_pData >= 32)
	{
		IR_pData = 0;
		// 验证数据正确性
		if((IR_data[0] == ~IR_data[1]) && (IR_data[2] == ~IR_data[3]))
		{
			IR_address = IR_data[0];
			IR_command = IR_data[2];
			IR_dataFlag = 1;
		}
		// 计时器停止
		timer0_run(0);
		IR_state == 0;
	}
}
